﻿using Application.Commons.Data;
using Domain.Entities.Loggers;
using FrameworkCore.Constants;
using FrameworkCore.Extensions;
using FrameworkCore.Interfaces;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

namespace Infrastructure.Events;

public class LoggerEventHandler : INotificationHandler<LoggerEvent>
{
    private readonly IDbContextFactory<ApplicationDbContext> _dbContextFactory;
    private readonly IGenerateIdService _generateIdService;
    public LoggerEventHandler(IServiceProvider serviceProvider, IGenerateIdService generateIdService)
    {
        _dbContextFactory = serviceProvider.GetRequiredService<IDbContextFactory<ApplicationDbContext>>();
        _generateIdService = generateIdService;
    }

    public  Task Handle(LoggerEvent notification, CancellationToken cancellationToken)
    {
        if (!(notification.Item.MessageTemplate.ToString() == NMessageTemplate.ActivityHistoryLog
            || notification.Item.Exception is not null))
            return Task.CompletedTask;

        var properties = notification.Item.Properties.ToDictionary(p => p.Key, p => p.Value.ToString());

        Logger logger = new Logger()
        {
            Id = _generateIdService.GenerateIdAsLong(),
            CustomerId = notification.CurrentUserService.CurrentUserId == 0 ? null : notification.CurrentUserService.CurrentUserId,
            Level = notification.Item.Level.ToString(),
            Message = notification.Item.RenderMessage(),
            MessageTemplate = notification.Item.MessageTemplate.ToString(),
            Exception = notification.Item.Exception?.ToString(),
            Timestamp = notification.Item.Timestamp.UtcDateTime.ToLocalTime(),
            TimestampLong = notification.Item.Timestamp.UtcDateTime.ToLocalTime().ToUnixTimestampMilliseconds(),
            Properties = properties.ToJson()
        };

        var dbcontext = _dbContextFactory.CreateDbContext();
        dbcontext.Add(logger);
        dbcontext.SaveChanges();

        return Task.CompletedTask;
    }
}

